﻿using System;
using System.ComponentModel;
using System.IO;
using System.Windows;
using System.Windows.Controls;

using Jonathan.Logic;

/*
 * Jonathan
 * Created by: Jonathan Montiverdi
 * Date: 7/23/2012
 * License: http://jonathan.codeplex.com/license
 */

namespace Jonathan.Interface
{
   /// <summary>
   /// Interaction logic for WikiUpload.xaml
   /// </summary>
   public partial class WikiUpload
   {
      private TextBox m_TxtFocused;
      
      /// <summary>
      /// Initializes a new wiki upload control.
      /// </summary>
      public WikiUpload()
      {
         InitializeComponent();
         this.LoadOtherLinks (0);
      }
      
      /// <summary>
      /// Occurs when then password in changes.
      /// </summary>
      /// <param name="sender">Password box.</param>
      /// <param name="e">RoutedEventArgs</param>
      private void PasswordChanged (object sender, RoutedEventArgs e)
      {
         var viewModel = (WikiUploadViewModel) this.DataContext;
         viewModel.Password = this._Password.Password;
      }
      
      /// <summary>
      /// Occurs when the control is loaded.
      /// </summary>
      /// <param name="sender">This control.</param>
      /// <param name="e">RoutedEventArgs</param>
      private void WikiUploadLoaded (object sender, RoutedEventArgs e)
      {
         var dataContext = this.DataContext as WikiUploadViewModel;
         if (dataContext != null)
            dataContext.PropertyChanged += WikiUploadChanged;
      }
      
      /// <summary>
      /// Occurs when a property in the data context has changed.
      /// </summary>
      /// <param name="sender"></param>
      /// <param name="e"></param>
      private void WikiUploadChanged (object sender, PropertyChangedEventArgs e)
      {
         if (this.DataContext == null) return;
         if (e.PropertyName == "Log")
            MainViewModel.GuiDispatcher.Invoke (new Action (() =>this._LogTextBox.ScrollToEnd ()), null);
      }
      
      /// <summary>
      /// Occurs when a text box is focused.
      /// </summary>
      /// <param name="sender">Focused text box.</param>
      /// <param name="e">RoutedEventArgs</param>
      private void TxtFocused (object sender, RoutedEventArgs e)
      {
         this.m_TxtFocused = (TextBox) sender;
      }
      
      /// <summary>
      /// Loads a list of other links.
      /// </summary>
      /// <param name="index">Index to select.</param>
      private void LoadOtherLinks (int index)
      {
         this._cmbOtherLink.Items.Clear ();
         this._cmbOtherLink.Items.Add ("wikipedia");
         this._cmbOtherLink.Items.Add ("Definition");
         var otherLinksFile = new FileInfo ("OtherLinks.txt");
         if (otherLinksFile.Exists)
         {
            using (var reader = new StreamReader (otherLinksFile.FullName))
            {
               while (reader.Peek () != -1)
               {
                  this._cmbOtherLink.Items.Add (reader.ReadLine ());
               }
            }
         }
         if (index == -1)
            this._cmbOtherLink.SelectedIndex = this._cmbOtherLink.Items.Count - 1;
         else
            this._cmbOtherLink.SelectedIndex = 0;
      }

      /// <summary>
      /// Adds center tags.
      /// </summary>
      /// <param name="sender">Center button.</param>
      /// <param name="e">RoutedEventArgs</param>
      private void CenterClick (object sender, RoutedEventArgs e)
      {
         this.AddTag ("<center>", "</center>");
      }

      /// <summary>
      /// Adds small tags.
      /// </summary>
      /// <param name="sender">Small button.</param>
      /// <param name="e">RoutedEventArgs</param>
      private void SmallClick (object sender, RoutedEventArgs e)
      {
         this.AddTag ("<small>", "</small>");
      }

      /// <summary>
      /// Adds bold tags.
      /// </summary>
      /// <param name="sender">Bold button.</param>
      /// <param name="e">RoutedEventArgs</param>
      private void BoldClick (object sender, RoutedEventArgs e)
      {
         this.AddTag ("'''", "'''");
      }

      /// <summary>
      /// Adds italic tags.
      /// </summary>
      /// <param name="sender">Italic button.</param>
      /// <param name="e">RoutedEventArgs</param>
      private void ItalicClick (object sender, RoutedEventArgs e)
      {
         this.AddTag ("''", "''");
      }

      /// <summary>
      /// Adds link tags.
      /// </summary>
      /// <param name="sender">Link button.</param>
      /// <param name="e">RoutedEventArgs</param>
      private void LinkClick (object sender, RoutedEventArgs e)
      {
         this.AddTag ("[[", "]]");
      }

      /// <summary>
      /// Adds other link tags.
      /// </summary>
      /// <param name="sender">Other link button.</param>
      /// <param name="e">RoutedEventArgs</param>
      private void OtherLinkClick (object sender, RoutedEventArgs e)
      {
         if (this._cmbOtherLink.SelectedValue.ToString () == "wikipedia")
            this.AddTag ("[[wikipedia:" + this._txtWikipedia.Text + "|", "]]");
         else if (this._cmbOtherLink.SelectedValue.ToString () == "Definition")
            this.AddTag ("{{Definition|", "|" + this._txtWikipedia.Text + "}}");
         else
            this.AddTag ("[[" + this._cmbOtherLink.SelectedValue + "|", "]]");
      }

      /// <summary>
      /// Adds break tags.
      /// </summary>
      /// <param name="sender">Break button.</param>
      /// <param name="e">RoutedEventArgs</param>
      private void BreakClick (object sender, RoutedEventArgs e)
      {
         this.AddTag ("<br />");
      }

      /// <summary>
      /// Adds the given tags to the selected text box.
      /// </summary>
      /// <param name="start"></param>
      /// <param name="end"></param>
      private void AddTag (string start, string end = "")
      {
         if (this.m_TxtFocused != null)
         {
            if (this.m_TxtFocused.SelectionLength > 0)
            {
               var lastChar = this.m_TxtFocused.Text [this.m_TxtFocused.SelectionStart + this.m_TxtFocused.SelectionLength - 1];
               if (lastChar == ' ')
                  this.m_TxtFocused.SelectionLength = this.m_TxtFocused.SelectionLength - 1;
               if (this.m_TxtFocused.Text [this.m_TxtFocused.SelectionStart] == ' ')
               {
                  this.m_TxtFocused.SelectionStart = this.m_TxtFocused.SelectionStart + 1;
                  this.m_TxtFocused.SelectionLength = this.m_TxtFocused.SelectionLength - 1;
               }
            }

            var index = this.m_TxtFocused.SelectionStart + this.m_TxtFocused.SelectionLength + start.Length + end.Length;
            var text = this.m_TxtFocused.Text.Insert (this.m_TxtFocused.SelectionStart + this.m_TxtFocused.SelectionLength, end);
            text = text.Insert (this.m_TxtFocused.SelectionStart, start);
            this.m_TxtFocused.Text = text;
            this.m_TxtFocused.SelectionStart = index;
            this.m_TxtFocused.SelectionLength = 0;
            this.m_TxtFocused.Focus ();
         }
      }

      /// <summary>
      /// Refreshes the list of other links
      /// </summary>
      /// <param name="sender">Refresh button.</param>
      /// <param name="e">RoutedEventArgs</param>
      private void RefreshOtherLinks (object sender, RoutedEventArgs e)
      {
         this.LoadOtherLinks (-1);
      }

      /// <summary>
      /// Adds the current itme to the other links text list.
      /// </summary>
      /// <param name="sender">Add button</param>
      /// <param name="e">RoutedEventArgs</param>
      private void AddOtherLinks (object sender, RoutedEventArgs e)
      {
         var otherLinksFile = new FileInfo ("OtherLinks.txt");
         using (var writer = new StreamWriter (otherLinksFile.FullName, true))
         {
            writer.WriteLine (this._txtWikipedia.Text);
            writer.Flush ();
            writer.Close ();
         }
         this.LoadOtherLinks (-1);
      }
   }
}